package core;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.util.Observable;
import java.util.Observer;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import projectiles.Projectile;
import towers.Tower;
import enemies.Enemy;

/**
 * @author Arno de Jager
 *
 */
public class View extends JPanel implements Observer {
	
	private Model model;
	private ViewMenu east;
	private NextWavePanel waveInfo;
	private Mouse mouse;

	public View( Model m, Controller c )
	{
		this.model = m;
		
		JPanel center = new JPanel(new BorderLayout());
		JPanel battlefield = new BattlefieldView();
		mouse = c.getMouse();
		battlefield.addMouseListener( mouse );
		battlefield.addMouseMotionListener(mouse);
		
		east = new ViewMenu(m, c);
		waveInfo = new NextWavePanel();
		
		// Bepaling van layout
		this.setLayout(new BorderLayout());
		add(center, BorderLayout.CENTER);
		add(east, BorderLayout.EAST);
		
		// Linker deel
		center.add(battlefield, BorderLayout.CENTER);
		center.add(waveInfo, BorderLayout.SOUTH);
	}
	
	public void update(Observable o, Object arg ) {
		// Update ook menu
		if ( arg.equals("updateStats"))
			east.update(o, arg);
		
		// Er is iets veranderd, repaint alles!
		else if ( arg.equals("repaint"))
			repaint();
		
		// Next wave info moet aangepast worden
		else if ( arg.equals("nextwave"))
			waveInfo.update(o, arg);
		else if (arg.equals("highscore"))
			showHighScore();
	}
	
	public void showHighScore(){
		DB.DBspel.createConnection();
		String arr[][] = DB.DBspel.getBest( model.getMap().getID() );
		
		StringBuffer s = new StringBuffer();
		for( int i = 0; i < arr.length; i++ ){
			//for( int j = 0; j < arr[i].length; j++ ){
				s.append( arr[i][0] + " \t" );
				s.append( arr[i][3] + " \t" );
			//}
			s.append( "\n" );
		}
		DB.DBspel.shutdown();
		JOptionPane.showMessageDialog(this, "Highscore\nName Email Map Score\n" + s.toString() );
	
	}
	
	
	class BattlefieldView extends JPanel {
		
		public void paintComponent(Graphics g) {
			//Eerst de map zodat deze niet bovenop staat
			model.getMap().draw(g, this.getBounds(), this);
			
			//Dan de torens zodat de projectielen niet 'onder' de toren door vliegen
			for(Tower t : model.getTowers()) {
				t.draw(g, this.getBounds(), this);
			}
			
			//En de enemys om dezelfde reden
			for(Enemy e : model.getEnemies()) {
				e.draw(g, this.getBounds(), this);
			}
			
			// Projectielen moeten over enemies en towers getekend worden
			for(Projectile p : model.getProjectiles()) {
				p.draw(g, this.getBounds(), this);
			}
			
			for(Explosion ex : model.getExplosions()) {
				ex.draw(g, this.getBounds(), this);
			}
			
			// Eventueel pause-icon
			if ( model.isPaused() )
				g.drawImage( new ImageIcon("images/pause.gif").getImage(), 5, 5, this );
			
			//mouse actie tekenen
			//controleren op nieuw geselecteerde tower
			if( mouse.getSelectedItem() != null && mouse.getSelectedItem().position == null){
				Point point = mouse.getMouseDot();
				//controleren of plek bezet is, en kleur toekennen
				if(mouse.placeOccupied( point )){
						g.setColor( Color.RED );
				}else{
						g.setColor( Color.GREEN );
				}
				//we moeten nu schaduw tekenen op veld
				g.drawRect(point.x-mouse.getSelectedItem().image.getIconHeight()/2, point.y-mouse.getSelectedItem().image.getIconWidth()/2, mouse.getSelectedItem().image.getIconWidth(), mouse.getSelectedItem().image.getIconHeight());
			}else if(mouse.getSelectedItem() != null && mouse.getSelectedItem().position != null){
				//er is een bestaande tower geselecteerd, vierkant eromheen tekenen.
				Point2D.Double point = mouse.getSelectedItem().position;
				g.setColor( Color.WHITE );
				g.drawRect( (int) point.getX()-3, (int) point.getY()-3, mouse.getSelectedItem().image.getIconWidth()+6, mouse.getSelectedItem().image.getIconHeight()+6);

			}
		}
	}
	
	class NextWavePanel extends JPanel {
		WaveInfo left = new WaveInfo( false );
		WaveInfo right = new WaveInfo( true );
		
		public NextWavePanel() {
			setLayout( new GridLayout(1,2));
			setPreferredSize( new Dimension(Model.battlefieldWidth, 60) );
			setBackground( new Color(60, 79, 104) );
			
			add( createPart( "Second Wave", left ) );
			add( createPart( "First Wave", right ) );
		}
		
		private JPanel createPart( String strTitle, JPanel content ) {
			JPanel title = new JPanel();
			title.setBackground( Color.black );
			
			JLabel titleLabel = new JLabel( strTitle );
			titleLabel.setForeground( Color.white );
			titleLabel.setFont( new Font("Verdana",Font.BOLD, 12) );
			title.add( titleLabel );
			
			JPanel x = new JPanel( new BorderLayout() );
			x.setBackground( new Color(60, 79, 104) );
			x.add( title, BorderLayout.NORTH );
			x.add( content, BorderLayout.CENTER  );
			
			return x;
		}

		public void update(Observable o, Object arg ) {
			left.update( o, arg );
			right.update( o, arg );
		}
		
		class WaveInfo extends JPanel {
			private String filename = "images/infantry.gif";
			private boolean firstWave;
			
			public WaveInfo( boolean firstWave ) {
				this.firstWave = firstWave;
				
				String waveType;
				
				if ( this.firstWave ) {
					waveType = model.getFirstWave();
				}
				else {
					waveType = model.getSecondWave();
				}
				
				System.out.println(waveType);
				
				if ( waveType.equals("Infantry") )
					filename = "images/infantry.gif";
				else if ( waveType.equals("Jeep") )
					filename = "images/jeep.gif";
				else if ( waveType.equals("Tank") )
					filename = "images/tank.gif";
			}
			
			public void paintComponent( Graphics g ) {
				// Aantal units
				g.setColor( Color.WHITE );
				g.setFont( new Font("Tahoma", Font.BOLD, 12) );
				
				int level = model.getStats().getLevel() + 1;
				if ( !this.firstWave )
					level++;
				
				int aantalEnemies = model.getCountEnemies( level );
				g.drawString( aantalEnemies + " unit" + (aantalEnemies == 1 ? "" : "s"), 160, 20);
				
				// 3 plaatjes van type vijand
				ImageIcon enemy = new ImageIcon( filename );
				int x = 240;
				
				Graphics2D g2d = (Graphics2D)g;
			    g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);

			    AffineTransform oldForm = g2d.getTransform();
			    AffineTransform newForm = (AffineTransform) g2d.getTransform().clone();
			    
			    newForm.rotate(Math.toRadians(90), x , 7);
			    
			    g2d.setTransform(newForm);
				g2d.drawImage( enemy.getImage(), x, 0, this );
				g2d.setTransform(oldForm);
			}
			
			public void update(Observable o, Object arg ) {
				String waveType;
				
				if ( this.firstWave ) {
					waveType = model.getFirstWave();
				}
				else {
					waveType = model.getSecondWave();
				}
				
				if ( waveType.equals("Infantry") )
					filename = "images/infantry.gif";
				else if ( waveType.equals("Jeep") )
					filename = "images/jeep.gif";
				else if ( waveType.equals("Tank") )
					filename = "images/tank.gif";
			}
		}
	}
}
